package io.renren.modules.app.service.impl;

import com.baomidou.mybatisplus.mapper.Condition;
import io.renren.common.utils.Query;
import io.renren.modules.app.dto.ListInOrderDTO;
import io.renren.modules.app.dto.common.BoolResult;
import io.renren.modules.app.enums.CheckOrderStatusEnum;
import io.renren.modules.app.enums.InOrderStatusEnum;
import io.renren.modules.app.enums.OutOrderStatusEnum;
import io.renren.modules.app.request.UpdateStepReq;
import io.renren.modules.app.request.checkorder.UpdateCheckOrderReq;
import io.renren.modules.app.request.intoorder.ListInOrderReq;
import io.renren.modules.app.request.intoorder.UpdateInOrderReq;
import io.renren.modules.app.request.outorder.UpdateOutOrderReq;
import io.renren.modules.app.service.ApiService;
import io.renren.modules.generator.dao.CheckOrderDao;
import io.renren.modules.generator.dao.InOrderDao;
import io.renren.modules.generator.dao.OutOrderDao;
import io.renren.modules.generator.entity.*;
import io.renren.modules.generator.service.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ApiServiceImpl implements ApiService {
    @Autowired
    InOrderService inOrderService;

    @Autowired
    OutOrderService outOrderService;
    @Autowired
    CheckOrderService checkOrderService;


    @Autowired
    InOrderItemService inOrderItemService;

    @Autowired
    ItemService itemService;

    @Override
    public List<ListInOrderDTO> listInOrder(ListInOrderReq request) {
        List<ListInOrderDTO> response = new ArrayList<>();
        Condition condition = Condition.create();
        condition.eq(StringUtils.isNotBlank(request.getCode()), "order_no", request.getCode());
        if (request.getStatus() > 0) {
            condition.eq("status", request.getStatus());
        } else {
            condition.eq("status", InOrderStatusEnum.初始化.getValue());
        }
        condition.ge(!Objects.isNull(request.getStartdate()), "create_time", request.getStartdate());
        condition.ge(!Objects.isNull(request.getEnddate()), "create_time", request.getEnddate());
        Map<String, Object> query = new HashMap<>();
        query.put("limit", request.getSize() + "");
        query.put("page", request.getIndex() + "");
        List<InOrderEntity> result = inOrderService.selectPage(new Query<InOrderEntity>(query).getPage(), condition).getRecords();
        if (result != null && result.size() > 0) {
            result.stream().forEach(x -> {
                ListInOrderDTO dto = new ListInOrderDTO();
                dto.setCode(x.getOrderNo());
                dto.setCreatedate(x.getCreateTime());
                dto.setPositionsum("");//todo 这是啥？
                dto.setStatus(x.getStatus());
                dto.setStatusstr(InOrderStatusEnum.getTextByValue(x.getStatus()));

                List<ListInOrderDTO.ListInOrderItemDTO> haha = new ArrayList<>();
                List<InOrderItemEntity> items = inOrderItemService.selectList(Condition.create().eq("order_no", x.getOrderNo()));
                items.stream().forEach(y -> {
                    ListInOrderDTO.ListInOrderItemDTO vo = new ListInOrderDTO.ListInOrderItemDTO();
                    BeanUtils.copyProperties(y, vo);
                    vo.setItemGuid(y.getItemGuid() + "-" + y.getBatchNo());
                    vo.setItemId(vo.getItemGuid());
                    haha.add(vo);
                });
                dto.setItems(haha);
                response.add(dto);
            });
        }
        return response;
    }

    @Autowired
    InOrderDao inOrderDao;

    @Autowired
    CheckOrderDao checkOrderDao;

    @Autowired
    OutOrderDao outOrderDao;

    @Autowired
    KucunService kucunService;

    @Override
    @Transactional
    public BoolResult updateInOrder(UpdateInOrderReq req) {
        int size = 0;
        int result = 0;
        try {
            List<InOrderItemEntity> updateList = new ArrayList<>();
            List<InOrderItemEntity> receiveList = new ArrayList<>();
            List<InOrderEntity> orders = inOrderService.selectList(Condition.create().eq("order_no", req.getCode()));
            if (orders != null & orders.size() > 0) {
                InOrderEntity orderEntity = orders.get(0);
                //未完成订单做操作
                if (orderEntity.getStatus() < InOrderStatusEnum.订单完成.getValue()) {//目前分拣系统不支持扣减操作

                    List<InOrderItemEntity> items = inOrderItemService.selectList(Condition.create().eq("order_no", req.getCode()));
                    size = items.size();
                    Map<String, UpdateStepReq.Item> reqMap = req.getPostitions().stream().collect(Collectors.toMap(UpdateStepReq.Item::getItemguid, x -> x));

                    for (InOrderItemEntity itemEntity : items) {
                        UpdateStepReq.Item iii = reqMap.get(itemEntity.getItemGuid() + "-" + itemEntity.getBatchNo());


                        //读取真实拣货数量iii
                        if (iii != null) {
                            //存储接收到的数据，用来更新库存
                            InOrderItemEntity receive = new InOrderItemEntity();
                            receive.setItemGuid(itemEntity.getItemGuid());
                            receive.setBatchNo(itemEntity.getBatchNo());
                            receive.setTrueQuantity(iii.getTruequantity());
                            receiveList.add(receive);
                            if (itemEntity.getTrueQuantity() == null) {
                                itemEntity.setTrueQuantity(iii.getTruequantity());//临时增加批次号，所以给分拣的信息要有所改变。
                            } else {
                                itemEntity.setTrueQuantity(//数量累加
                                        iii.getTruequantity() + itemEntity.getTrueQuantity()
                                );
                            }
                            updateList.add(itemEntity);
                        }

                        if (!itemEntity.getTrueQuantity().equals(itemEntity.getQuantity())) {//拣货数量有偏差
                            result = result << 1;
                        } else {
                            result = (result << 1) + 1;
                        }
                    }
                    //只调用一次的情况下，可以先进行item更新，认定每次都是有效操作
                    if (updateList.size() > 0) {
                        inOrderItemService.updateBatchById(updateList);

                    }
                    if (receiveList.size() > 0) {
                        List<KucunEntity> updateKuncun = new ArrayList<>();
                        receiveList.stream().forEach(y -> {
                            KucunEntity en = new KucunEntity();
                            en.setItemGuid(y.getItemGuid());
                            en.setBatchNo(y.getBatchNo());
                            en.setAmount(y.getTrueQuantity());
                            en.setVirAmount(y.getTrueQuantity());
                            updateKuncun.add(en);
                        });
                        kucunService.increaceKucun(updateKuncun);
                    }
                    //主表状态更新
                    if (result != 0 && result == (int) (Math.pow(2, size) - 1)) {
                        orderEntity.setStatus(InOrderStatusEnum.订单完成.getValue());
                        orderEntity.setFinishTime(new Date());
                        orderEntity.setFinishUser("分拣系统");
                        inOrderService.updateById(orderEntity);
                    } else {
                        //增加锁表，防止重复修改

//                    InOrderEntity updateEntity = inOrderDao.selectByIdForUpdate(orderEntity.getId());
                        if (req.getStatus() == InOrderStatusEnum.拣货完成.getValue()) {//只有拣货完成状态下才能认定拣货不符
                            orderEntity.setStatus(InOrderStatusEnum.拣货数量不符.getValue());
                            inOrderService.updateById(orderEntity);
                        }
                    }

                }
            }
            return BoolResult.success();
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw e;
        }
    }

    @Autowired
    CheckOrderItemService checkOrderItemService;


    public static void main(String[] args) {
        long re = 0;
        re = (re + 1) << 1;
        System.out.println(Long.toBinaryString(re));
        re = (re << 1) + 1;
        System.out.println(Long.toBinaryString(re));
        re = (re << 1) + 1;
        System.out.println(Long.toBinaryString(re));
        re = (re << 1) + 1;
        System.out.println(Long.toBinaryString(re));
        re = re << 2;
        System.out.println(Long.toBinaryString(re));

        System.out.println(Long.toBinaryString((long) Math.pow(2, 5) - 1));

    }

    @Override
    public BoolResult updateCkOrder(UpdateCheckOrderReq req) {
        int size = 0;
        long result = 0;
        List<CheckOrderItemEntity> updateList = new ArrayList<>();
        List<CheckOrderEntity> orders = checkOrderService.selectList(Condition.create().eq("order_no", req.getCode()));
        if (orders != null & orders.size() > 0) {
            CheckOrderEntity orderEntity = orders.get(0);
            //未完成订单做操作
            if (orderEntity.getStatus() < CheckOrderStatusEnum.库存一致.getValue()) {

                List<CheckOrderItemEntity> items = checkOrderItemService.selectList(Condition.create().eq("order_no", req.getCode()));
                size = items.size();
                Map<String, UpdateStepReq.Item> reqMap = req.getPostitions().stream().collect(Collectors.toMap(UpdateStepReq.Item::getItemguid, x -> x));

                for (CheckOrderItemEntity itemEntity : items) {
                    UpdateStepReq.Item iii = reqMap.get(itemEntity.getItemGuid() + "-" + itemEntity.getBatchNo());
                    //读取真实拣货数量
                    if (iii != null
//                            && itemEntity.getTrueQuantity() < itemEntity.getQuantity()
                    ) {
                        if (itemEntity.getTrueQuantity() == null) {
                            itemEntity.setTrueQuantity(iii.getTruequantity());
                        } else {
                            itemEntity.setTrueQuantity(//数量累加
                                    iii.getTruequantity() + itemEntity.getTrueQuantity()
                            );
                        }
                        updateList.add(itemEntity);
                    }
                    if (itemEntity.getTrueQuantity() < itemEntity.getQuantity()) {//实际数量少

                        result = result << 1;

                    } else if (itemEntity.getTrueQuantity() > itemEntity.getQuantity()) {//实际数量多//最多能比对32个商品出错
                        if (result == 0) {
                            result = (result + 1) << 1;
                        } else {
                            result = result << 2;
                        }
                    } else {
                        result = (result << 1) + 1;
                    }
                }
                if (updateList.size() > 0) {
                    checkOrderItemService.updateBatchById(updateList);
                }

                //主表状态更新
                int maybe = (int) (Math.pow(2, size) - 1);
                if (result != 0 && result == maybe) {
                    orderEntity.setStatus(CheckOrderStatusEnum.库存一致.getValue());
                    orderEntity.setFinishTime(new Date());
                    orderEntity.setFinishUser("分拣系统");
                    checkOrderService.updateById(orderEntity);
                } else {
                    //增加锁表，防止重复修改
//                    CheckOrderEntity updateEntity = checkOrderDao.selectByIdForUpdate(orderEntity.getId());
                    //只有拣货完成状态下才能认定拣货不符
                    if (req.getStatus() == CheckOrderStatusEnum.盘点完成.getValue()) {
                        if (result < maybe) {
                            orderEntity.setStatus(CheckOrderStatusEnum.实际少.getValue());
                        } else {
                            orderEntity.setStatus(CheckOrderStatusEnum.实际多.getValue());
                        }
                        checkOrderService.updateById(orderEntity);
                    }
                }
            }
        }
        return BoolResult.success();
    }

    @Autowired
    OutOrderItemService outOrderItemService;

    @Override
    public BoolResult updateOutOrder(UpdateOutOrderReq req) {
        int size = 0;
        int result = 0;
        List<OutOrderItemEntity> updateList = new ArrayList<>();
        List<InOrderItemEntity> receiveList = new ArrayList<>();
        try {
            List<OutOrderEntity> orders = outOrderDao.selectList(Condition.create().eq("order_no", req.getCode()));
            if (orders != null & orders.size() > 0) {
                OutOrderEntity orderEntity = orders.get(0);
                //未完成订单做操作
                if (orderEntity.getStatus() < OutOrderStatusEnum.出库完成.getValue()) {
                    List<OutOrderItemEntity> items = outOrderItemService.selectList(Condition.create().eq("order_no", req.getCode()));
                    size = items.size();
                    Map<String, UpdateStepReq.Item> reqMap = req.getPostitions().stream().collect(Collectors.toMap(UpdateStepReq.Item::getItemguid, x -> x));

                    for (OutOrderItemEntity itemEntity : items) {
                        UpdateStepReq.Item iii = reqMap.get(itemEntity.getItemGuid() + "-" + itemEntity.getBatchNo());

                        //读取真实拣货数量
                        if (iii != null) {
                            //存储接收到的数据，用来更新库存
                            InOrderItemEntity receive = new InOrderItemEntity();
                            receive.setItemGuid(itemEntity.getItemGuid());
                            receive.setBatchNo(itemEntity.getBatchNo());
                            receive.setTrueQuantity(iii.getTruequantity());
                            receiveList.add(receive);
                            if (itemEntity.getTrueQuantity() == null) {
                                itemEntity.setTrueQuantity(iii.getTruequantity());
                            } else {
                                itemEntity.setTrueQuantity(//数量累加
                                        iii.getTruequantity() + itemEntity.getTrueQuantity()
                                );
                            }
                            updateList.add(itemEntity);
                        }

                        if (!itemEntity.getTrueQuantity().equals(itemEntity.getQuantity())) {//拣货数量有偏差
                            result = result << 1;
                        } else {
                            result = (result << 1) + 1;
                        }
                    }
                    if (updateList.size() > 0) {
                        outOrderItemService.updateBatchById(updateList);
                    }
                    if (receiveList.size() > 0) {
                        List<KucunEntity> updateKuncun = new ArrayList<>();
                        receiveList.stream().forEach(y -> {
                            KucunEntity en = new KucunEntity();
                            en.setItemGuid(y.getItemGuid());
                            en.setBatchNo(y.getBatchNo());
                            en.setAmount(y.getTrueQuantity());
                            updateKuncun.add(en);
                        });
                        kucunService.decreaceKucun(updateKuncun);
                    }
                    //主表状态更新
                    if (result != 0 && result == (int) (Math.pow(2, size) - 1)) {
                        orderEntity.setStatus(OutOrderStatusEnum.出库完成.getValue());
                        orderEntity.setFinishTime(new Date());
                        orderEntity.setFinishUser("分拣系统");
                        outOrderService.updateById(orderEntity);
                    } else {
                        //增加锁表，防止重复修改
                        if (req.getStatus() == OutOrderStatusEnum.操作完成.getValue()) {//只有拣货完成状态下才能认定拣货不符
//                    OutOrderEntity updateEntity = outOrderDao.selectByIdForUpdate(orderEntity.getId());
                            orderEntity.setStatus(OutOrderStatusEnum.出库数量不一致.getValue());
                            outOrderService.updateById(orderEntity);
                        }
                    }
                }
            }
            return BoolResult.success();
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw e;
        }
    }


    @Autowired
    OpInfoService opInfoService;

    @Override
    public BoolResult updateStep(UpdateStepReq req) {
        if (StringUtils.isEmpty(req.getCode())) {
            return BoolResult.fail("单号不能为空");
        }

        if (req.getStatus() < 1 || req.getStatus() > 3) {
            return BoolResult.fail("状态（status）不在应处理范围(1-3)，请确认操作是否正确");
        }

        boolean isUpdateData = req.getPositions() != null && req.getPositions().size() > 0;

        switch (req.getOrdertype()) {
            case InOrder:
                //更新主表状态，状态不可回退
                InOrderEntity inOrderEntity = new InOrderEntity();
                inOrderEntity.setStatus(req.getStatus());
                inOrderService.update(inOrderEntity, Condition.create().eq("order_no", req.getCode()).lt("status", req.getStatus()));
                if (isUpdateData) {//如果是提交数据
                    UpdateInOrderReq updateInOrderReq = new UpdateInOrderReq();
                    updateInOrderReq.setCode(req.getCode());
                    updateInOrderReq.setPostitions(req.getPositions());
                    updateInOrderReq.setStatus(req.getStatus());
                    this.updateInOrder(updateInOrderReq);
                }
                break;
            case OutOrder:

                //更新主表状态，状态不可回退
                OutOrderEntity outOrderEntity = new OutOrderEntity();
                outOrderEntity.setStatus(req.getStatus());
                outOrderService.update(outOrderEntity, Condition.create().eq("order_no", req.getCode()).lt("status", req.getStatus()));
                if (isUpdateData) {//如果是提交数据
                    UpdateOutOrderReq updateoutOrderReq = new UpdateOutOrderReq();
                    updateoutOrderReq.setCode(req.getCode());
                    updateoutOrderReq.setPostitions(req.getPositions());
                    updateoutOrderReq.setStatus(req.getStatus());
                    this.updateOutOrder(updateoutOrderReq);
                }
                break;

            case CheckOrder:
                //更新主表状态，状态不可回退
                CheckOrderEntity checkOrderEntity = new CheckOrderEntity();
                checkOrderEntity.setStatus(req.getStatus());
                checkOrderService.update(checkOrderEntity, Condition.create().eq("order_no", req.getCode()).lt("status", req.getStatus()));
                if (isUpdateData) {//如果是提交数据
                    UpdateCheckOrderReq updateCkOrderReq = new UpdateCheckOrderReq();
                    updateCkOrderReq.setCode(req.getCode());
                    updateCkOrderReq.setPostitions(req.getPositions());
                    updateCkOrderReq.setStatus(req.getStatus());
                    this.updateCkOrder(updateCkOrderReq);
                }
                break;
        }
        //记录操作记录
        OpInfoEntity opInfo = new OpInfoEntity();
        opInfo.setOpTime(req.getOptime());
        opInfo.setOrderNo(req.getCode());
        opInfo.setStation(req.getStation());
//        opInfo.setUser(); //todo 需要关联查询员工-工位表 （目前没有）

        try {
            opInfoService.insert(opInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return BoolResult.success();
    }

}
